package freaks.terah.gui;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.JProgressBar;

import freaks.terah.model.AI;
import freaks.terah.model.Data;
import freaks.terah.model.FileIO;
import freaks.terah.model.PlayerModel;

public class Gui implements ActionListener {

	// Frames
	private JFrame loadFrame;
	private JFrame frame;
	private IntroFrame initFrame;
	private NewFrame newFrame;
	private NewPlayerFrame newPlayerFrame;
	private NewMainFrame newMainFrame;
	private JProgressBar bar;
	private JPanel activePanel;
	private Timer timer;
	
	// Global Data
	private DefaultListModel<String> players;
	private int ID;
	private int progress;
	private int turn;
	
	private FileOutputStream st;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Gui window = new Gui(1);
					window.frame.setTitle("Terah Nova v2");
					window.frame.setSize(new Dimension(310, 220));
					window.frame.setLocationRelativeTo(null);
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public DefaultListModel<String> getPlayers()
	{
		return players;
	}
	
	public void setID(int anId) {
		ID = anId;
	}
	
	public int getID() {
		return ID;
	}
	
	public void setTurn(int turn) {
		this.turn = turn;
	}

	public int getTurn() {
		return turn;
	}
	
	public void setNewFrame(int role)
	{
		int playerNumber = 0;
		if (role == 1)
		{
			boolean valid = false;
			String code = "";
			while (!valid)
			{
			    
				code = JOptionPane.showInputDialog("Enter your starting code:", "");
			    
			    if (code == null)
			    {
			    	return;
			    }
			    
			    if (!code.trim().equalsIgnoreCase(""))
			    {
			    	try {
			    	    FileIO io = new FileIO();
			    	    playerNumber = Integer.parseInt(io.decode(code.substring(0, 2))[0].getData());
			    	    Data[] data = io.decode(io.decrypt(code.substring(2), 1, playerNumber));
			    	    ID = Integer.parseInt(data[0].getData());
			    	    players.clear();
			    	    int playNum = Integer.parseInt(data[2].getData());
			    	    for (int i = 0; i < playNum; i++)
			    	    	players.addElement(data[3+i].getData());
			    	    valid=true;
			    	} catch (Exception e) {
			    		JOptionPane.showMessageDialog(frame, "Invalid server message", "Error", JOptionPane.ERROR_MESSAGE);
			    	}
			    }
			}
			
			
			frame.remove(activePanel);
			frame.getContentPane().add(newPlayerFrame);
			activePanel = newPlayerFrame;
			newPlayerFrame.setTempRole(role);
			newPlayerFrame.setTempPlayerNumber(playerNumber);
			frame.validate();
			frame.repaint();
			frame.setSize(new Dimension(630, 300));
			return;
		}
		
		frame.remove(activePanel);
		frame.getContentPane().add(newFrame);
		activePanel = newFrame;
		frame.validate();
		frame.repaint();
		frame.setSize(new Dimension(630, 300));
	}

	/**
	 * Create the application.
	 */
	public Gui(int mode) {
		if (mode == 0)
		{
			loadFrame = new JFrame();
			loadFrame.setBounds(100, 100, 450, 300);
			bar = new JProgressBar();
			bar.setBounds(150, 100, 200, 30);
			loadFrame.add(bar);
			progress = 0;
			loadFrame.setVisible(true);
			timer = new Timer(10, this);
			timer.start();
			initialize();
			loadFrame.setVisible(false);
		} else {
			setID(1);
			startLogFile("/Users/Chris/Desktop/log.txt");
			players = new DefaultListModel<String>();
			players.addElement("PICU");
			players.addElement("Bit");
			players.addElement("Tera");
			players.addElement("Dakota");
			int playerNum = 4;
			AI[] ais = new AI[4];
			for (int i = 0; i < playerNum;i++)
			{
				ais[i] = new AI(this, i+1);
				ais[i].init(0, i);
			}
			
			for (int turn = 1; turn < 108; turn ++)
			{
				setTurn(turn);
				for (int i = 0; i < playerNum;i++)
					ais[i].doTurn();
			}
			
			saveLogFile();
			System.exit(0);
		}
	}

	private void startLogFile(String string) {
		File f = new File(string);
		try {
			st = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private void saveLogFile() {
		try {
			st.flush();
			st.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void addLogString(String string) {
		try {
			st.write(string.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void addLogLine(String string) {
		try {
			String s2 = string + "\n";
			st.write(s2.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		players = new DefaultListModel<String>();
		initFrame = new IntroFrame(this);
		progress = 10;
		initFrame.setBounds(0, 0, 450, 278);
		newFrame = new NewFrame(this);
		progress = 30;
		newFrame.setBounds(0, 0, 630, 300);
		newMainFrame = new NewMainFrame(this);
		progress = 80;
		newMainFrame.setBounds(0, 0, 720, 650);
		newPlayerFrame = new NewPlayerFrame(this);
		newPlayerFrame.setBounds(0, 0, 630, 300);
		progress = 100;
		
		frame.getContentPane().setLayout(null);
		activePanel = initFrame;
		timer.stop();
		frame.remove(bar);
		frame.getContentPane().add(activePanel);
	}

	public void setMainFrame(String data, String serverData) throws Exception {
		frame.remove(activePanel);
		frame.getContentPane().add(newMainFrame);
		activePanel = newMainFrame;
		frame.setSize(new Dimension(750, 680));
		frame.setLocationRelativeTo(null);
		newMainFrame.setInitData(data, serverData);
		newMainFrame.validate();
		newMainFrame.repaint();
		frame.validate();
		frame.repaint();
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		bar.setValue(progress);
		bar.repaint();
		timer.restart();
	}

	public void setNewPlayerFrame(int role, int playerNumber) {
		frame.remove(activePanel);
		frame.getContentPane().add(newPlayerFrame);
		newPlayerFrame.setTempRole(role);
		newPlayerFrame.setTempPlayerNumber(playerNumber);
		activePanel = newPlayerFrame;
		frame.validate();
		frame.repaint();
		frame.setSize(new Dimension(630, 300));
	}

	public Data[] getGlobalData(PlayerModel aModel) {
		int totalDataSize = 7 + players.getSize();
		Data[] data = new Data[totalDataSize];
		data[0] = new Data(ID);
		data[1] = new Data(aModel.getRole());
		data[2] = new Data(turn);
		data[3] = new Data(players.getSize());
		
		for (int i = 0; i < players.getSize(); i++)
			data[4 + i] = new Data((String)players.get(i));
		
		data[4 + players.getSize()] = new Data(aModel.getPlayerNumber());
		data[5 + players.getSize()] = new Data(aModel.getGoal());
		data[6 + players.getSize()] = new Data(aModel.getShip());

		return data;
	}
}
